{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import random\n",
    "import time\n",
    "import collections\n",
    "from tqdm import tqdm\n",
    "sns.set()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_dataset(words, n_words, atleast=1):\n",
    "    count = [['PAD', 0], ['GO', 1], ['EOS', 2], ['UNK', 3]]\n",
    "    counter = collections.Counter(words).most_common(n_words)\n",
    "    counter = [i for i in counter if i[1] >= atleast]\n",
    "    count.extend(counter)\n",
    "    dictionary = dict()\n",
    "    for word, _ in count:\n",
    "        dictionary[word] = len(dictionary)\n",
    "    data = list()\n",
    "    unk_count = 0\n",
    "    for word in words:\n",
    "        index = dictionary.get(word, 0)\n",
    "        if index == 0:\n",
    "            unk_count += 1\n",
    "        data.append(index)\n",
    "    count[0][1] = unk_count\n",
    "    reversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))\n",
    "    return data, count, dictionary, reversed_dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('shakespeare.txt') as fopen:\n",
    "    shakespeare = fopen.read().split()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "vocabulary_size = len(list(set(shakespeare)))\n",
    "data, count, dictionary, rev_dictionary = build_dataset(shakespeare, vocabulary_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "GO = dictionary['GO']\n",
    "PAD = dictionary['PAD']\n",
    "EOS = dictionary['EOS']\n",
    "UNK = dictionary['UNK']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Generator:\n",
    "    def __init__(self, size_layer, num_layers, embedded_size,\n",
    "                 from_dict_size, to_dict_size, learning_rate, batch_size):\n",
    "        \n",
    "        def cells(reuse=False):\n",
    "            return tf.nn.rnn_cell.GRUCell(size_layer,reuse=reuse)\n",
    "        \n",
    "        self.X = tf.placeholder(tf.int32, [None, None])\n",
    "        self.Y = tf.placeholder(tf.int32, [None, None])\n",
    "        self.X_seq_len = tf.count_nonzero(self.X, 1, dtype=tf.int32)\n",
    "        self.Y_seq_len = tf.count_nonzero(self.Y, 1, dtype=tf.int32)\n",
    "        batch_size = tf.shape(self.X)[0]\n",
    "        \n",
    "        encoder_embedding = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1))\n",
    "        decoder_embedding = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1))\n",
    "        \n",
    "        self.cells = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)])\n",
    "        self.encoder_state = self.cells.zero_state(\n",
    "            dtype = tf.float32, batch_size = tf.shape(self.X)[0]\n",
    "        )\n",
    "        \n",
    "        _, encoder_state = tf.nn.dynamic_rnn(\n",
    "            cell = self.cells, \n",
    "            inputs = tf.nn.embedding_lookup(encoder_embedding, self.X),\n",
    "            sequence_length = self.X_seq_len,\n",
    "            initial_state = self.encoder_state,\n",
    "            dtype = tf.float32)\n",
    "        main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "        decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "        dense = tf.layers.Dense(to_dict_size)\n",
    "        decoder_cells = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)])\n",
    "        \n",
    "        training_helper = tf.contrib.seq2seq.TrainingHelper(\n",
    "                inputs = tf.nn.embedding_lookup(decoder_embedding, decoder_input),\n",
    "                sequence_length = self.Y_seq_len,\n",
    "                time_major = False)\n",
    "        training_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = decoder_cells,\n",
    "                helper = training_helper,\n",
    "                initial_state = encoder_state,\n",
    "                output_layer = dense)\n",
    "        training_decoder_output, self.training_state, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = training_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = tf.reduce_max(self.Y_seq_len))\n",
    "        self.training_logits = training_decoder_output.rnn_output\n",
    "        \n",
    "        predicting_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(\n",
    "                embedding = decoder_embedding,\n",
    "                start_tokens = tf.tile(tf.constant([GO], dtype=tf.int32), [batch_size]),\n",
    "                end_token = EOS)\n",
    "        predicting_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = decoder_cells,\n",
    "                helper = predicting_helper,\n",
    "                initial_state = encoder_state,\n",
    "                output_layer = dense)\n",
    "        predicting_decoder_output, self.predict_state, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = predicting_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = tf.reduce_max(self.X_seq_len))\n",
    "        self.predicting_ids = predicting_decoder_output.sample_id\n",
    "        \n",
    "        masks = tf.sequence_mask(self.Y_seq_len, tf.reduce_max(self.Y_seq_len), dtype=tf.float32)\n",
    "        self.cost = tf.contrib.seq2seq.sequence_loss(logits = self.training_logits,\n",
    "                                                     targets = self.Y,\n",
    "                                                     weights = masks)\n",
    "        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)\n",
    "        \n",
    "        y_t = tf.argmax(self.training_logits,axis=2)\n",
    "        y_t = tf.cast(y_t, tf.int32)\n",
    "        self.prediction = tf.boolean_mask(y_t, masks)\n",
    "        mask_label = tf.boolean_mask(self.Y, masks)\n",
    "        correct_pred = tf.equal(self.prediction, mask_label)\n",
    "        correct_index = tf.cast(correct_pred, tf.float32)\n",
    "        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "learning_rate = 0.001\n",
    "batch_size = 32\n",
    "sequence_length = 64\n",
    "epoch = 3000\n",
    "num_layers = 2\n",
    "size_layer = 256\n",
    "possible_batch_id = range(len(data) - sequence_length - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.reset_default_graph()\n",
    "sess = tf.InteractiveSession()\n",
    "model = Generator(size_layer, num_layers, size_layer, len(dictionary), \n",
    "                len(dictionary), learning_rate,batch_size)\n",
    "sess.run(tf.global_variables_initializer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train_random_batch():\n",
    "    LOST, ACCURACY = [], []\n",
    "    pbar = tqdm(range(epoch), desc = 'epoch')\n",
    "    batch_x = np.zeros((batch_size, sequence_length))\n",
    "    for n in range(batch_size):\n",
    "        index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "        batch_x[n] = data[index:index + sequence_length]\n",
    "    initial_state = sess.run(model.predict_state, feed_dict = {model.X: batch_x})\n",
    "    for i in pbar:\n",
    "        batch_x = np.zeros((batch_size, sequence_length))\n",
    "        batch_y = np.zeros((batch_size, sequence_length + 1))\n",
    "        for n in range(batch_size):\n",
    "            index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "            batch_x[n] = data[index:index + sequence_length]\n",
    "            batch_y[n] = data[index + 1:index + sequence_length + 1] + [EOS]\n",
    "        accuracy, _, loss, initial_state = sess.run([model.accuracy, model.optimizer, \n",
    "                                                     model.cost, model.predict_state], \n",
    "                                       feed_dict = {model.X: batch_x, \n",
    "                                                    model.Y: batch_y,\n",
    "                                                    model.encoder_state: initial_state})\n",
    "        ACCURACY.append(accuracy); LOST.append(loss)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    return LOST, ACCURACY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch: 100%|██████████| 3000/3000 [31:13<00:00,  1.62it/s, accuracy=0.434, cost=2.9]   \n"
     ]
    }
   ],
   "source": [
    "LOST, ACCURACY = train_random_batch()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize = (15, 5))\n",
    "plt.subplot(1, 2, 1)\n",
    "EPOCH = np.arange(len(LOST))\n",
    "plt.plot(EPOCH, LOST)\n",
    "plt.xlabel('epoch')\n",
    "plt.ylabel('loss')\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(EPOCH, ACCURACY)\n",
    "plt.xlabel('epoch')\n",
    "plt.ylabel('accuracy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_based_sequence(length_sentence):\n",
    "    index = np.random.randint(0, len(data) - sequence_length - 1)\n",
    "    x = np.array([data[index:index + sequence_length]])\n",
    "    initial_state, ids = sess.run([model.predict_state,model.predicting_ids], \n",
    "                                  feed_dict = {model.X: x})\n",
    "    ids = ids[0].tolist()\n",
    "\n",
    "    while len(ids) < length_sentence:\n",
    "        initial_state, ids_ = sess.run([model.predict_state,model.predicting_ids], \n",
    "                                      feed_dict = {model.X: [ids[-sequence_length:]],\n",
    "                                                  model.encoder_state: initial_state})\n",
    "        ids.extend(ids_[0].tolist())\n",
    "\n",
    "    return ' '.join([rev_dictionary[i] for i in ids])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "be the way to toe. First Murderer: What is my offence? First Murderer: What is the news of this new world, with the field? Second Murderer: What is his name? Second Murderer: What is his name? Second Murderer: What is his name? Second Murderer: I warrant thee, he was a traitor and his throats are gone To help him from his government. First Murderer: the duke to be deposed? Gardener: Depress'd he is the chiefest duke of his lawful crown. He gave him in his mercy, He is not his, He cannot proceed and he shall not live His honours with his bridal-day, He cried 'The courage to his arms, He prays his doubled spirit Re-quicken'd his own soul and his son are fallen with him. First Murderer: king that Henry will him king. EXETER: He is the king that he had held his power, He was his policy to counterfeit, He cannot guess and his crown his sides, His father was, he hath borne his grave? He prays his father hath been in peace and his followers? He is his policy and his body, He cannot guess of his country. He that he did him, and his followers? He was his policy to counterfeit, His father and his father gave him the root Of his own person; he hath been in his face, And with his bridal-day, he wiped his doubled spirit Re-quicken'd his poor father should have been a man. Second Watchman: He is his name? and he hath hid his wrinkled front; And he had been in his bed? First Watchman: He was a poor man; with his great blood, He hath made his person, and his followers? Is he not in his bed? WARWICK: He was the god of his own bringings-forth, and he did bend his natural steeds, And rob his own and so took his body To choke him like a thousand-fold he EOS had been in his bed? First Watchman: He was a poor man; his looks and his followers? He gave him in his bed, and his followers? He gave him in the malmsey-butt and he of his leather bottle. His wonted his father cried in his devouring paws; And with his name? and he returns, Splitting his head and grinning to his own person; And heard his honours even: He cried in his bed, And his pond fish'd with his chin and murder's thoughts. He throws to hide his brother! He was his name? and he lives to him, And his apparent passage who, the duke of him; he wept, And his poor father did not live in his digressing son. DUKE OF YORK: He would he speak? EOS his head with panting. His chronicle thus writ: 'The man was noble, And he himself thou, and his lustful bed and himself, And with his loins his babe's, betrays to slander, His sting and his own soul and the king's, his appetite, To his surname he took his body To choke his glories! GEORGE: And his poor father did he had his father's EOS head with panting. Now did he walks, his doubled spirit Re-quicken'd his own soul and his followers? He gave him in his face, And with his devouring paws; and leaves himself, And he to his bed, and his followers? Now he hath been his welcomes Then, by the sudden, he did his appetite, And choke he were as long to his bed, And his with his devouring paws; And so he walks, 'What he is gone, and his pond A traitor steeped in his loins his appetite, He cried in his devouring paws; And he did beat his honours with him. First Conspirator: And he hath seized his honours with his eyes, He doth choke the subject did in his face, And with his loins he kiss'd his his devouring paws; And he did sleep his honours with his oak. He cried as he under ease his body and his father doubly install'd; And consequently, his leaves with his devouring paws; And he did courage in his bed? First Watchman: He hath he in his bed? First Watchman: He hath the duke that did his father gave him his shoulder-bone; And he steeds, His head in his devouring paws; And he did courage in his bed? First Watchman: He is his name? and he is his heir; And his poor father were his father in his hearts, And set his head to his teeth, he hath drunk, and all his body To choke him in his devouring paws; And he did all the rest did EOS His father were his father and his father hath been in his face, And with his devouring paws; and his virtues Did not, he did his bed, and his followers? Is he himself in his bed? First Watchman: He is his name? and he hath hid his wrinkled front; And he in his devouring paws; And by the same and drowsy courtesy, which he father hath been his son; He hath his heir; and his grandsire is his heir; And his poor father were his father in his hearts, and his followers? He prays his father hath been in his bed, And all his summer leaves his will: PRINCE: His wonted his father gave him in the oak. He cried like a swine he lies! Grim And thrice hath been his policy and his body, And then his doubled to his bed, he cried 'God save him!' He cried as his virtues He gave him in his face, And with his summer leaves his sire He gave him in his face, And with his summer leaves his spring, And he that did the duke that did his father gave him his visage now his friends in his oak. He cried with oak. O monstrous and his father's bed, And with his loins he kiss'd his summer leaves his grave? He cried aloud, 'Hold, friends! Oxford, on his neck, And with his devouring paws; and leaves his bed, And all his summer leaves his will: PRINCE: His wonted the duke were now in his face, And with\n"
     ]
    }
   ],
   "source": [
    "print(generate_based_sequence(1000))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
